package com.gmail.dengtao.joe.commons.stream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.gmail.dengtao.joe.commons.util.ByteUtils;

/**
 * GZIP byte stream opreations.
 * @author <a href="mailto:joe.dengtao@gmail.com">DengTao</a>
 * @version 1.0
 * @since 1.0
 */
public class GZipStream {

	private static final int BUFFER_SIZE = 512;

	/**
	 * Compress plain bytes to gzip format bytes.
	 * @param plain bytes needs to compress
	 * @return compressed bytes in gzip format
	 * @throws IOException
	 * @since 1.0
	 */
	public static byte[] compress(byte[] plain) throws IOException {
	    ByteArrayOutputStream os = null;
		GZIPOutputStream gos = null;
		try {
			os = new ByteArrayOutputStream(1024);
			gos = new GZIPOutputStream(os);
			gos.write(plain);
			gos.finish();
			gos.flush();
		    return os.toByteArray();
		} catch (IOException e) {
			throw e;
		} finally {
			if (gos != null) gos.close();
			if (os != null) os.close();
		}
	}
	
	/**
	 * Deompress gzip format bytes to normal bytes.
	 * @param compressed bytes needs to decompress
	 * @return bytes decompressed from compressed bytes
	 * @throws IOException
	 * @since 1.0
	 */
	public static byte[] decompress(byte[] compressed) throws IOException {
		ByteArrayInputStream is = null;
		GZIPInputStream gis = null;
		try {
			is = new ByteArrayInputStream(compressed);
			gis = new GZIPInputStream(is, BUFFER_SIZE);
			byte[] data = new byte[BUFFER_SIZE];
			byte[] plain = ByteUtils.EMPTY_BYTE_ARRAY;
			int rl = 0;
			while ((rl = gis.read(data)) != -1) {
				plain = ByteUtils.merge(plain, ByteUtils.cut(data, rl));
		    }
			return plain;
		} catch (IOException e) {
			throw e;
		} finally {
			if (gis != null) gis.close();
			if (is != null) is.close();
		}
	}
}